<!-- 网络拓扑图配置 -->
<template>
	<div class="it-road-editor-container">
		<!-- 搜索条件 -->
		<!-- <el-form :model="formData" :inline="true" :label-width="100">
			<el-form-item label="应用系统" prop="systemId">
				<el-select v-model="formData.systemId" placeholder="请选择应用系统">
					<el-option v-for="item in state.systemOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
				</el-select>
			</el-form-item>
		</el-form> -->
		<yd-form :options="formOptions" :model="formData" :btns="formBtns" @formInit="formInited"></yd-form>

		<br />

		<!-- 绘制区 -->
		<div id="container" v-loading="loadingGraphFlag"></div>

		<!-- 节点属性编辑弹出框 -->
		<el-dialog
			v-model="open.nodeAttrDialog"
			:title="title"
			width="900px"
			center
			append-to-body
			:close-on-click-modal="false"
			@close="cancel"
			@closed="handlerClosed"
		>
			<div id="dialogDiv" :style="{ height: addDialogForm.nodeEditHeight }" class="it-road-add-dialog-div">
				<el-scrollbar style="height: 100%">
					<div>
						<div class="lineDivClass"></div>
						<div class="segmentHeadDiv">基本信息</div>
						<div class="lineDivClass"></div>
						<br />
						<div id="segmentContentDiv">
							<el-form ref="topoForm" :model="form" :rules="rules" label-width="130px" size="small">
								<el-row>
									<el-col :span="12">
										<el-form-item label="元素名称" prop="componentName">
											<el-input v-model="form.componentName" placeholder="请输入网端名称" style="width: 200px" maxlength="50" />
										</el-form-item>
									</el-col>
									<el-col :span="12">
										<el-form-item label="基础设施" prop="deviceType">
											<el-cascader
												v-model="form.deviceType"
												:options="dialogOptions.deviceOptions"
												placeholder="请选择"
												style="width: 200px"
											></el-cascader>
										</el-form-item>
									</el-col>
								</el-row>
								<el-row>
									<el-col :span="12">
										<el-form-item label="所在位置" prop="netType">
											<el-select v-model="form.netType" placeholder="请选择" style="width: 200px">
												<el-option v-for="(dict, index) in dialogOptions.netOptions" :key="index" :label="dict.label" :value="dict.label"></el-option>
											</el-select>
										</el-form-item>
									</el-col>
									<el-col :span="12">
										<el-form-item label="连接方式" prop="connectType">
											<el-select v-model="form.connectType" placeholder="请选择" style="width: 200px">
												<el-option
													v-for="(dict, index) in dialogOptions.connectOptions"
													:key="index"
													:label="dict.label"
													:value="dict.label"
												></el-option>
											</el-select>
										</el-form-item>
									</el-col>
								</el-row>
							</el-form>
						</div>
					</div>

					<div v-if="addDialogForm.showComponentResource">
						<div class="lineDivClass"></div>
						<div class="componentHeadDiv">IP信息</div>
						<div class="lineDivClass"></div>
						<div id="componentDiv">
							<br />
							<!--按钮-->
							<el-row :gutter="10" class="mb8" style="padding-left: 17px">
								<el-col :span="1.5">
									<div @click="addComponentHandle">
										<svg-icon icon-class="yd-icon-plus" class="icon-style" circle></svg-icon>
										<span class="icon-title" style="margin-left: 2px; margin-right: 15px; font-size: 14px"> 新增 </span>
									</div>
								</el-col>
								<el-col :span="1.5">
									<div
										:class="buttonIsDisabled(addDialogForm.component.singleSelect)"
										:disabled="addDialogForm.component.singleSelect || addDialogForm.component.adding"
										@click="updateComponentHandle"
									>
										<svg-icon icon-class="yd-icon-edit" class="icon-style" circle></svg-icon>
										<span class="icon-title" style="margin-left: 2px; margin-right: 15px; font-size: 14px"> 修改 </span>
									</div>
								</el-col>
								<el-col :span="1.5">
									<div
										:class="buttonIsDisabled(addDialogForm.component.multipleSelect)"
										:disabled="addDialogForm.component.multipleSelect"
										@click="deleteComponentHandle"
									>
										<svg-icon icon-class="yd-icon-delete" class="icon-style" circle></svg-icon>
										<span class="icon-title" style="margin-left: 2px; margin-right: 15px; font-size: 14px"> 删除 </span>
									</div>
								</el-col>
								<el-col :span="1.5">
									<div @click="saveComponentHandle">
										<svg-icon icon-class="yd-icon-plus" class="icon-style" circle></svg-icon>
										<span class="icon-title" style="margin-left: 2px; margin-right: 15px; font-size: 14px"> 保存 </span>
									</div>
								</el-col>
								<el-col :span="1.5">
									<div @click="cancelComponentHandle">
										<svg-icon icon-class="yd-icon-delete" class="icon-style" circle></svg-icon>
										<span class="icon-title" style="margin-left: 2px; margin-right: 15px; font-size: 14px"> 取消 </span>
									</div>
								</el-col>
							</el-row>

							<!--查询列表-->
							<el-table
								ref="componentTable"
								v-loading="addDialogForm.component.loading"
								:data="addDialogForm.component.componentList"
								@selection-change="componentSelectionChangeHandle"
							>
								<el-table-column type="selection" width="50" align="center" />
								<el-table-column label="IP地址" align="center" prop="ip">
									<template #default="scope">
										<span v-if="scope.row.enable">
											<el-input v-model="scope.row.ip" maxlength="30"></el-input>
										</span>
										<span v-else>{{ scope.row.ip }}</span>
									</template>
								</el-table-column>
							</el-table>

							<!--分页-->
							<div style="float: right; margin-top: 10px">
								<el-pagination
									v-show="addDialogForm.component.total > 0"
									v-model:current-page="addDialogForm.component.formData.pageNum"
									v-model:page-size="addDialogForm.component.formData.pageSize"
									layout="total, sizes, prev, pager, next, jumper"
									:page-sizes="[10, 20, 30, 50, 100]"
									:total="addDialogForm.component.total"
									@current-change="searchComponentHandler(null)"
									@size-change="searchComponentHandler(null, 1)"
								/>
							</div>
						</div>
					</div>
				</el-scrollbar>
			</div>

			<template #footer>
				<el-button type="primary" @click="submitForm">确 定</el-button>
				<el-button @click="cancel">取 消</el-button>
			</template>
		</el-dialog>

		<el-dialog
			v-model="deleteDialogOpen"
			title="删除节点"
			width="400px"
			center
			append-to-body
			:close-on-click-modal="false"
			@closed="handleCloseDeleteNode"
		>
			<div style="font: 16px bold; margin-bottom: 15px">
				<el-icon color="#E8A13B"><WarningFilled /></el-icon> &nbsp;{{ deleteLabel }}
			</div>
			<el-radio v-model="isRecursiveDelete" :label="true">递归删除</el-radio>
			<div class="tip-text">将删除本元素及其所有子元素</div>
			<el-radio v-model="isRecursiveDelete" :label="false">非递归删除</el-radio>
			<div class="tip-text">仅删除本元素，保留其所有子元素</div>
			<template #footer>
				<el-button type="primary" @click="deleteNodeHandle">确 定</el-button>
				<el-button @click="handleCloseDeleteNode">取 消</el-button>
			</template>
		</el-dialog>
	</div>
</template>

<script setup name="NetworkTopoConfig" lang="ts">
import G6 from '@antv/g6';
import registerShape from './shape';
import registerBehavior from './behavior';
import {
	getNetTopology,
	deleteLink,
	updateComponentInfo,
	deleteComponentInfo,
	addComponentInfo,
	getDeviceInfo,
	addIpConfig,
	updateIpConfig,
	deleteIpConfig,
	getAllIp,
	getNodeInfo,
	setComponentLocation,
} from '@/api/management/segmentManage/networkTopoConfig';
import { queryDictByType, queryAppSystemOptions } from '@/api/search/searchOptions.js';

import topoEditDisabledPng from '@/assets/images/admin/topology/edit-disabled.png';
import topoEditPng from '@/assets/images/admin/topology/edit.png';
import topoDeleteDisabledPng from '@/assets/images/admin/topology/delete-disabled.png';
import topoDeletePng from '@/assets/images/admin/topology/delete.png';
import minimapDisabledPng from '@/assets/images/admin/topology/minimap-disabled.png';
import minimapPng from '@/assets/images/admin/topology/minimap.png';
import { getCurrentInstance, onMounted, reactive, ref, toRefs, watch, nextTick } from 'vue';
import { useRoute } from 'vue-router';
// import useUserStore from '@/store/common/user';
import { GraphData } from '@/components/YdItRoad/itRoad-type';

const { proxy }: any = getCurrentInstance();
const route = useRoute();

// g6 graph对象
let graph = reactive<anyObj>({});
// 遮罩层
const loading = ref(true);
// 弹出层标题
const title = ref('');
// 是否显示弹出层
let open = reactive({
	nodeAttrDialog: false,
	componentAttrDialog: false,
});
//弹出框相关
let addDialogForm = reactive<anyObj>({
	//弹出框高度
	nodeEditHeight: '800px',
	//是否显示组件和资源
	showComponentResource: true,
	activeTabs: 'segment',
	secondActiveTabs: 'ipPort',
	//组件相关
	component: {
		loading: true,
		componentList: [],
		singleSelect: true,
		multipleSelect: true,
		adding: false,
		ids: null,
		total: 0,
		formData: {
			pageNum: 1,
			pageSize: 10,
		},
	},
});
// 弹框下拉项
let dialogOptions = reactive<anyObj>({
	deviceOptions: [],
	netOptions: [],
	connectOptions: [
		{ label: 'TCP', sort: 1 },
		{ label: 'TCP长连接', sort: 2 },
		{ label: '异步双工模式的长连接', sort: 3 },
	],
});
// 节点属性表单参数
const data = reactive<anyObj>({
	form: {},
	currentContextItem: {},
});
const { form, currentContextItem } = toRefs(data);
// 节点信息
let nodeItem = reactive<any>({});
// 表单校验
const rules = ref<anyObj>({
	componentName: [{ required: true, message: '元素名称不能为空', trigger: 'blur' }],
	deviceType: [{ required: true, message: '请选择基础设施', trigger: 'change' }],
	netType: [{ required: true, message: '请选择所在位置', trigger: 'change' }],
	connectType: [{ required: true, message: '请选择连接方式', trigger: 'change' }],
});
// 搜索表单数据
let formData = reactive({
	...route.query,
});
// 图形加载中
const loadingGraphFlag = ref(false);
// 连线菜单文本
const linkMenuText = ref('连线模式');
// 组件显示/隐藏
const isShowComponent = ref(false);
// 删除节点弹框
const deleteLabel = ref('');
const isRecursiveDelete = ref(false);
const deleteDialogOpen = ref(false);
// 权限数组
// const permissionsArry = useUserStore().permissions;
// const roles = useUserStore().roles;
// 保存点击右键的HTML
const clickElement = ref('');
// 记录点击右键时应该展示菜单的个数
const clickElementCount = ref(0);
let isFirst = true;

watch(
	currentContextItem,
	(newVal: any, oldVal: any) => {
		const editBackEl = document.getElementsByClassName('edit-back')[0] as HTMLDivElement;
		const deleteBackEl = document.getElementsByClassName('delete-back')[0] as HTMLDivElement;
		if (newVal && Object.keys(newVal).length > 0) {
			if (newVal.getModel().type === 'myCubicHorizontal') {
				editBackEl.style.backgroundImage = 'url(' + topoEditDisabledPng + ')';
				editBackEl.style.cursor = 'not-allowed';
			} else {
				editBackEl.style.backgroundImage = 'url(' + topoEditPng + ')';
				editBackEl.style.cursor = 'pointer';
			}
			deleteBackEl.style.backgroundImage = 'url(' + topoDeletePng + ')';
			deleteBackEl.style.cursor = 'pointer';
		} else {
			if (!isFirst) {
				editBackEl.style.backgroundImage = 'url(' + topoEditDisabledPng + ')';
				editBackEl.style.cursor = 'not-allowed';
				deleteBackEl.style.backgroundImage = 'url(' + topoDeleteDisabledPng + ')';
				deleteBackEl.style.cursor = 'not-allowed';
			}
			isFirst = false;
		}
	},
	{ deep: true, immediate: true }
);

watch(
	() => formData.systemId,
	(newval: any) => {
		sessionStorage.setItem('networkTopoConfig.systemId', newval);
	},
	{ deep: true }
);

const state = reactive<any>({
	systemOptions: [],
});

const formBtns = reactive<BtnType[]>([
	{
		type: 'primary',
		text: '查询',
		handler: searchHandler,
	},
]);

const formOptions = reactive<FormOptionType>([
	{
		type: 'select',
		label: '应用系统',
		prop: 'systemId',
		selectKey: 'value',
		api: {
			name: 'queryAppSystemOptions',
		},
		attrs: {
			clearable: false,
		},
	},
]);

function searchSystemOptionsFn() {
	queryAppSystemOptions().then((res: any) => {
		state.systemOptions = res.data;
		if (res.data.length) {
			formData.systemId = res.data[0].value;
		}
	});
}

onMounted(async () => {
	await searchSystemOptionsFn();
	// 禁用浏览器的默认行为(解决在火狐浏览器下拖拽会打开新页面)
	document.body.ondrop = function (event) {
		event.preventDefault();
		event.stopPropagation();
	};
	// 初始化graph
	initGraph();
	// 边监听事件
	// 点击时选中，再点击时取消
	graph.on('edge:click', (ev: any) => {
		console.log('onClick2', ev);
		const edge = ev.item;
		const statNames = ['selected', 'active', 'hover'];
		for (let i = 0; i < statNames.length; i++) {
			graph.findAllByState('node', statNames[i]).forEach((node: any) => {
				graph.clearItemStates(node, statNames[i]);
			});
			graph.findAllByState('edge', statNames[i]).forEach((node: any) => {
				if (node.getModel().id !== edge.getModel().id) {
					graph.clearItemStates(node, statNames[i]);
				}
			});
		}
		// 选中边
		graph.setItemState(edge, 'selected', !edge.hasState('selected')); // 切换选中
	});
	// 移入边时高亮显示
	graph.on('edge:mouseenter', (ev: any) => {
		const edge = ev.item;
		graph.setItemState(edge, 'active', true);
	});
	// 移出边时去除高亮
	graph.on('edge:mouseleave', (ev: any) => {
		const edge = ev.item;
		//如果边是选中状态，那么移动鼠标，那么保留选中状态，给删除用。
		if (edge.hasState('selected')) {
			return;
		}
		graph.setItemState(edge, 'active', false);
	});
	// 节点的双击事件, 打开节点详情弹窗
	graph.on('node:dblclick', (ev: any) => {
		nodeItem = null;
		// 表单重置
		reset();
		nodeItem = ev.item;
		const item = ev.item;
		// 设置点击的节点为选中状态
		graph.setItemState(nodeItem, 'selected', true);
		currentContextItem.value = ev.item;
		editNodeHandle(nodeItem);
	});
	// 节点和边的鼠标按下事件，用于在右键点击时调整菜单的样式
	graph.on('node:mousedown', (ev: any) => {
		console.log('node:mousedown');
		currentContextItem.value = ev.item;
		nodeItem = ev.item;
		// 隐藏提示框延迟执行
		setTimeout(function () {
			Array.from(document.getElementsByClassName('g6-node-tooltip')).forEach((t: any) => {
				t.style.visibility = 'hidden';
			});
		}, 300);
	});
	graph.on('edge:mousedown', (ev: any) => {
		currentContextItem.value = ev.item;
	});
	// let node =  editorsNodeItroad
	graph.on('node:mouseleave', (ev: any) => {
		const node = ev.item;
		//如果边是选中状态，那么移动鼠标，那么保留选中状态，给删除用。
		if (node.hasState('selected')) {
			return;
		}
		console.log('node:mouseleave');
		graph.setItemState(node, 'active', false);
	});
	//鼠标点击画布清除选中的节点或边临时item
	graph.on('canvas:click', (ev: any) => {
		currentContextItem.value = null;
		nodeItem = null;
		const statNames = ['selected', 'active', 'hover'];
		for (let i = 0; i < statNames.length; i++) {
			graph.findAllByState('node', statNames[i]).forEach((node: any) => {
				graph.clearItemStates(node, statNames[i]);
			});
			graph.findAllByState('edge', statNames[i]).forEach((node: any) => {
				graph.clearItemStates(node, statNames[i]);
			});
		}
	});
	// 监听被拖拽的元素在目标元素上同时鼠标放开触发的事件，此事件作用在目标元素上
	graph.on('drop', (ev: any) => {
		if (ev.originalEvent.dataTransfer) {
			// 拖拽新增节点
			const sourceFlag = ev.originalEvent.dataTransfer.getData('Text');
			if (sourceFlag === 'addNodeByImg') {
				draggableAddNode(ev);
			}
		} else {
			// 拖拽更新节点位置
			if (currentContextItem.value !== null) {
				const nodeModel = currentContextItem.value.getModel();
				// 拖动为节点类型时才更新位置
				if (nodeModel.type === 'editorsNodeItroad') {
					setComponentLocation({
						type: '1',
						locationX: parseInt(nodeModel.x),
						locationY: parseInt(nodeModel.y),
						systemId: formData.systemId,
						nodeId: nodeModel.id,
					}).then((res) => {});
				}
			}
		}
	});
});

function formInited() {
	console.log('forminited', formData.systemId);
	nextTick(() => {
		registerShape(G6);
		registerBehavior(G6, formData.systemId);

		searchHandler();
	});
}

// 遍历权限
function traversepermission() {
	clickElementCount.value = 0;
	// roles.forEach((item) => {
	// if (item === 'admin') {
	document.getElementById('addRoad')!.style.display = 'block';
	document.getElementById('editRoad')!.style.display = 'block';
	document.getElementById('deleteRoad')!.style.display = 'block';
	document.getElementById('assemblyRoad')!.style.display = 'block';
	clickElement.value =
		`<ul style="color:#333">
          <li opera='1'  id="linkMenuText">` +
		linkMenuText.value +
		`</li>
          <li opera='2'>删除</li>
        </ul>`;
	// return;
	// }
	// });

	// permissionsArry.forEach((item) => {
	// 	switch (item) {
	// 		case 'itRoad:addRoad':
	// 			document.getElementById('addRoad').style.display = 'block';
	// 			break;
	// 		case 'itRoad:editRoad':
	// 			document.getElementById('editRoad').style.display = 'block';
	// 			break;
	// 		case 'itRoad:deleteRoad':
	// 			clickElementCount.value++;
	// 			document.getElementById('deleteRoad').style.display = 'block';
	// 			clickElement.value = `<ul>
	//                           <li opera='2'>删除</li>
	//                         </ul>`;
	// 			break;
	// 		case 'itRoad:assemblyRoad':
	// 			document.getElementById('assemblyRoad').style.display = 'block';
	// 			break;
	// 		case 'itRoad:linkMenuText':
	// 			clickElementCount.value++;
	// 			clickElement.value =
	// 				`<ul>
	//                           <li opera='1' id="linkMenuText">` +
	// 				linkMenuText.value +
	// 				`</li>
	//                         </ul>`;
	// 			break;
	// 	}
	// });
	// if (clickElementCount.value === 2) {
	// 	clickElement.value =
	// 		`<ul>
	//                         <li opera='1' id="linkMenuText">` +
	// 		linkMenuText.value +
	// 		`</li>
	//                         <li opera='2'>删除</li>
	//                       </ul>`;
	// }
}
// 清除所有边和节点的状态
function resetNodeEdgeState() {
	const statNames = ['selected', 'active', 'hover'];
	for (let i = 0; i < statNames.length; i++) {
		graph.findAllByState('node', statNames[i]).forEach((node: any) => {
			graph.clearItemStates(node, statNames[i]);
		});
		graph.findAllByState('edge', statNames[i]).forEach((node: any) => {
			graph.clearItemStates(node, statNames[i]);
		});
	}
}
// 重置画布
function resetCanvas() {
	currentContextItem.value = null;
	nodeItem = null;
	const editBackEl = document.getElementsByClassName('edit-back')[0] as HTMLElement;
	const deleteBackEl = document.getElementsByClassName('delete-back')[0] as HTMLElement;
	editBackEl.style.backgroundImage = 'url(' + topoEditDisabledPng + ')';
	editBackEl.style.cursor = 'not-allowed';
	deleteBackEl.style.backgroundImage = 'url(' + topoDeleteDisabledPng + ')';
	deleteBackEl.style.cursor = 'not-allowed';
	// 清除所有边和节点的状态
	resetNodeEdgeState();
	// 隐藏提示框
	let g6NodeTooltipEle = document.getElementsByClassName('g6-node-tooltip');
	if (g6NodeTooltipEle.length > 0) {
		Array.from(g6NodeTooltipEle).forEach((t: any) => {
			t.style.visibility = 'hidden';
		});
	}
	// 切换回默认模式
	linkMenuText.value = '连线模式';
	graph.setMode('default');
}
// 表单搜索
function searchHandler() {
	// 重置画布
	resetCanvas();
	// 初始化graph数据
	const id = formData.systemId;
	loadingGraphFlag.value = true;
	getNetTopology(id).then((res: any) => {
		loadingGraphFlag.value = false;

		if (res.code === 0) {
			const d: GraphData = {
				nodes: [],
				edges: [],
			};
			// const nodes = res.data.componentInfoList;
			// const edges = res.data.componentRelationList;
			//当前系统没有节点，清空返回
			if (!res.data || res.data.length === 0) {
				graph.data(d);
				graph.render();
				return;
			}
			// 处理ip信息，以便鼠标移到节点时显示ip信息
			// const components = res.data.ipSource;
			// let cpMap = new Map();
			// for (const component of components) {
			// 	let ipList = [];
			// 	if (cpMap.get(component.componentId) !== null) {
			// 		ipList = cpMap.get(component.componentId);
			// 		ipList.push(component.ip);
			// 	} else {
			// 		ipList.push(component.ip);
			// 	}
			// 	cpMap.set(component.componentId, ipList);
			// }
			// 处理数据：节点和边
			formatGraphData(res.data);
			// eslint-disable-next-line no-inner-declarations
			function formatGraphData(arr: any, idKey = 'id') {
				arr.forEach((node: any) => {
					node.id = node.id + '';
					let index = d.nodes.findIndex((n: any) => n.id === node.id);
					// 没有的节点才加进去
					if (index === -1) {
						// 设置x、y坐标
						node.x = node.locationX;
						node.y = node.locationY;
						node.ipList = node.ipAndPort;
						d.nodes.push(node);
					}
					if (node.childNodes instanceof Array) {
						node.childNodes.forEach((subNode: any) => {
							d.edges.push({
								source: node[idKey] + '',
								target: subNode[idKey] + '',
							});
						});
						formatGraphData(node.childNodes);
					}
				});
			}
			// // 节点赋值
			// for (const node of nodes) {
			// 	const ipList = cpMap.get(node.id);
			// 	data.nodes.push({
			// 		id: node.id + '',
			// 		componentName: node.componentName,
			// 		netType: node.netType,
			// 		connectType: node.connectType,
			// 		deviceType: node.deviceType,
			// 		x: parseInt(node.locationX),
			// 		y: parseInt(node.locationY),
			// 		ipList: ipList,
			// 	});
			// }
			// // 边赋值
			// for (const edge of edges) {
			// 	data.edges.push({
			// 		source: edge.preComponentId + '',
			// 		target: edge.componentId + '',
			// 		label: edge.connectType,
			// 	});
			// }
			graph.data(d);
			graph.render();
			console.log('d--------------', d);
			if (isShowComponent.value) {
				showComponentFun();
			}
		} else {
			proxy.$modal.msgError(res.msg);
		}
	});
}
// 拖动图弹出弹窗添加节点
function draggableAddNode(event: any) {
	// 表单重置
	reset();
	nodeItem = null;
	open.nodeAttrDialog = true;
	title.value = '新增';
	form.value.x = event.x;
	form.value.y = event.y;

	//新增节点，隐藏IP
	addDialogForm.showComponentResource = false;
	//设置高度
	addDialogForm.nodeEditHeight = '250px';
}
/** 提交按钮 **/
function submitForm() {
	// TODO 改基础设施值的表现方式deviceType为string
	proxy.$refs['topoForm'].validate((valid: any) => {
		if (valid) {
			// 克隆表单数据对象
			const newNode = JSON.parse(JSON.stringify(form.value));
			const deviceT = newNode.deviceType[1];
			newNode.deviceType = deviceT;
			// newNode.componentName = newNode.componentName;
			newNode.locationX = newNode.x;
			newNode.locationY = newNode.y;
			//下面的命名和G6有冲突
			if (nodeItem) {
				// 修改
				let tempNode = JSON.parse(JSON.stringify(newNode));
				tempNode.systemId = formData.systemId;
				updateComponentInfo(tempNode).then((res: any) => {
					if (res.code === 0) {
						proxy.$modal.msgSuccess(res.msg);
					} else {
						proxy.$modal.msgError(res.msg);
					}
				});
			} else {
				// 新增
				let tempNode = JSON.parse(JSON.stringify(newNode));
				tempNode.systemId = formData.systemId;
				addComponentInfo(tempNode).then((res) => {
					if (res.code === 0) {
						// 添加节点，节点id默认字符串，不然不能连续
						newNode.id = res.data + '';
						graph.addItem('node', newNode);
						// 移除所有选中状态节点的选中状态
						graph.findAllByState('node', 'selected').forEach((node: any) => {
							graph.clearItemStates(node, 'selected');
						});
						proxy.$modal.msgSuccess(res.msg);
					} else {
						proxy.$modal.msgError(res.msg);
					}
				});
			}
			open.nodeAttrDialog = false;
		}
	});
}
// 取消按钮
function cancel() {
	open.nodeAttrDialog = false;
	addDialogForm.secondActiveTabs = 'ipPort';
	addDialogForm.component.componentList = [];
}
// 表单重置
function reset() {
	form.value = {
		id: undefined,
		componentName: undefined,
		deviceType: undefined,
		netType: undefined,
		connectType: undefined,
		x: 0,
		y: 0,
	};
	if (proxy.$refs['topoForm']) {
		proxy.$refs['topoForm'].resetFields();
	}
}
// 初始化graph
function initGraph() {
	const width = document.getElementById('container')?.scrollWidth;
	const height = document.getElementById('app')!.scrollHeight - 200;
	// 菜单插件
	const menu = new G6.Menu({
		className: 'g6-contextMenu',
		offsetY: -10,
		itemTypes: ['node'],
		getContent: (e: any) => {
			const outDiv = document.createElement('contextMenu') as HTMLDivElement;
			if (clickElement.value !== undefined) {
				outDiv.innerHTML = clickElement.value;
			}
			if (outDiv.firstChild !== null) {
				outDiv.firstChild.childNodes.forEach((node: any) => {
					if (node.id === 'linkMenuText') {
						if (graph.getCurrentMode() === 'default') {
							node.innerText = '连线模式';
						} else {
							node.innerText = '退出连线';
						}
					}
				});
			}
			return outDiv;
		},
		handleMenuClick(target: any) {
			// G6插件存在bug，多次点击会触发多次该方法，故在每次右击时将对应item存储到currentContextItem中，并在操作结束后将其设置成null
			if (currentContextItem.value) {
				const itemId = currentContextItem.value._cfg.id;
				const opera = target.getAttribute('opera');
				if (opera === '0') {
					// 编辑组件属性
					open.componentAttrDialog = true;
				} else if (opera === '1') {
					// 连线
					const mode = graph.getCurrentMode();
					if (mode === 'default') {
						resetNodeEdgeState();
						linkMenuText.value = '默认模式';
						graph.setMode('addEdge');
					} else {
						linkMenuText.value = '连线模式';
						graph.setMode('default');
						graph.getEdges().forEach((edge: any) => {
							const target = edge.getModel().target;
							if (target.x !== undefined && target.y !== undefined) {
								graph.removeItem(edge);
							}
						});
					}
				} else if (opera === '2') {
					// 删除
					const nodeModel = currentContextItem.value.getModel();
					const type = nodeModel.type;
					if (type === 'myCubicHorizontal') {
						proxy.$modal
							.confirm('是否需要删除已经选中的边', '警告', {
								confirmButtonText: '确定',
								cancelButtonText: '取消',
								cancelButtonClass: 'confirm-rigth-cancel-button',
								type: 'warning',
							})
							.then(() => {
								//如果线没有连接两端，那么目标为对象，如果连接目标为string
								if (typeof nodeModel.target === 'object') {
									searchHandler();
									return;
								}
								deleteLink({
									nodeId: nodeModel.target,
									parentNodeId: nodeModel.source,
									systemId: formData.systemId,
								}).then((res) => {
									if (res.code === 0) {
										graph.removeItem(graph.findById(nodeModel.id));
										proxy.$modal.msgSuccess('删除成功');
									} else {
										proxy.$modal.msgError('删除失败');
									}
								});
								currentContextItem.value = null;
							})
							.catch(function () {
								//proxy.$modal.msgError("删除失败");
							});
					} else {
						console.log('nodemo', nodeModel);
						deleteLabel.value = '请选择已选中的节点' + nodeModel.name + '的删除方式';
						deleteDialogOpen.value = true;
					}
				}
			}
		},
	});
	const graphObj = new G6.Graph({
		// 图的 DOM 容器，可以传入该 DOM 的 id 或者直接传入容器的 HTML 节点对象
		container: 'container',
		// 指定画布宽度，单位为 'px'
		width,
		// 指定画布高度，单位为 'px'
		height,
		// 是否开启画布自适应。开启后图自动适配画布大小
		//fitView: true,
		// v3.5.1 后支持。开启后，图将会被平移，图的中心将对齐到画布中心，但不缩放。优先级低于 fitView
		fitCenter: true,
		// 最小缩放比例
		minZoom: 0.5,
		// 最大缩放比例
		maxZoom: 2,
		// 渲染方式，该配置项除 V3.3.x 外其他版本均支持 'canvas' / 'svg'
		// renderer: 'canvas',
		// 是否启用 stack，即是否开启 redo & undo 功能，该配置项 V3.6 及以上版本支持
		enabledStack: true,
		// 设置画布的模式
		modes: {
			default: [
				// 拖拽画布
				'drag-canvas',
				// 缩放画布
				'zoom-canvas',
				// 拖拽节点
				'drag-node',
				// 节点高亮(自定义)
				'activate-node',
				// 鼠标移入显示提示框
				{
					type: 'tooltip',
					// 是否出现，当右键菜单出现时隐藏悬浮框
					shouldBegin: (ev) => {
						let flag = true;
						let g6ContextMenu = document.getElementsByClassName('g6-contextMenu');
						if (g6ContextMenu.length > 0) {
							Array.from(g6ContextMenu).forEach((t: any) => {
								if (t.style.visibility === 'visible') {
									flag = false;
								}
							});
						}
						// 当显示组件信息时，隐藏悬浮框
						if (isShowComponent.value) {
							flag = false;
						}
						return flag;
					},
					formatText(model: any) {
						let text = 'IP：';
						if (model.ipList && model.ipList.length > 0) {
							model.ipList.forEach((ipVal: any) => {
								text = text + '<br/>' + ipVal;
							});
						}
						return text;
					},
				},
			],
			// Adding node mode
			addNode: ['click-add-node'],
			// Adding edge mode
			addEdge: ['click-add-edge'],
		},
		// 向 graph 注册插件
		plugins: [menu],
		// 布局配置项，使用 type 字段指定使用的布局方式，type 可取以下值：random, radial, mds, circular, fruchterman, force, dagre，各布局详细的配置请参考
		/*layout: {
        type: 'dagre',
        rankdir: 'LR',
        nodesep: 30,
        ranksep: 100,
    },*/
		// 默认状态下节点的配置，比如 type, size, color。会被写入的 data 覆盖
		defaultNode: {
			type: 'editorsNodeItroad',
			style: {
				stroke: '#72CC4A',
			},
		},
		// 默认状态下边的配置，比如 type, size, color。会被写入的 data 覆盖
		defaultEdge: {
			type: 'myCubicHorizontal',
			labelCfg: {
				refY: 10,
				style: {
					fill: '#333333',
				},
			},
		},
		// 各个状态下节点的样式，例如 hover、selected，3.1 版本新增
		nodeStateStyles: {},
		// 各个状态下边的样式，例如 hover、selected，3.1 版本新增
		edgeStateStyles: {},
	});
	graph = graphObj;
	// 设置工具栏
	const toolbar = new G6.ToolBar({
		getContent: () => {
			const outDiv = document.createElement('div');
			outDiv.style.width = '335px';
			outDiv.style.height = '65px';
			outDiv.innerHTML = `<ul>
        <li code="add"  id="addRoad" style="display:block">
          <div>
            <div
              class="add-back"
              style="margin-left: -2px;"
              draggable="true"
              ondragstart="event.dataTransfer.setData('Text', 'addNodeByImg')">
            </div>
            <div style="cursor: default;">新增</div>
          </div>
        </li>
        <li code="edit" id="editRoad" style="display:block">
          <div>
            <div class="edit-back" style="margin-left: -2px;"></div>
            <div style="cursor: default;">编辑</div>
          </div>
        </li>
        <li code="delete" id="deleteRoad" style="display:block">
          <div>
            <div class="delete-back" style="margin-left: -2px;"></div>
            <div style="cursor: default;">删除</div>
          </div>
        </li>
        <li code="showComponent" id="assemblyRoad" style="display:block">
          <div>
            <div class="show-component-back" style="margin-left: -2px;"></div>
            <div id="showOrHideText" style="cursor: default;">隐藏</div>
          </div>
        </li>
      </ul>`;
			return outDiv;
		},
		// 点击工具栏
		handleClick: (code, graph) => {
			if (code === 'edit') {
				if (currentContextItem.value && currentContextItem.value.getModel().type === 'editorsNodeItroad') {
					editNodeHandle();
				}
			} else if (code === 'delete') {
				removeItemHandle();
			} else if (code === 'showComponent') {
				toggleShowComponent();
			}
		},
		//按钮css 控制
		buttonIsDisabled(val: any, callBack: any) {
			if (val === 'check') {
				if (callBack()) {
					return 'enabled';
				}
				return 'disabled';
			}
			if (val) {
				return 'disabled';
			}
			return 'enabled';
		},
	});
	graph.addPlugin(toolbar);
	traversepermission();
}
//按钮是否触发控制
function clickCallBack(val, callBack, checkCallBack) {
	if (val === 'check') {
		if (checkCallBack()) {
			return callBack();
		}
	}
	if (!val) {
		return callBack();
	}
}
function removeItemHandle() {
	if (currentContextItem.value === null || currentContextItem.value === '') {
		proxy.$modal.msgWarning('请选择要删除的边或者节点。');
		return;
	} else {
		const nodeModel = currentContextItem.value.getModel();
		// 删除 componentName
		const type = nodeModel.type;
		if (type === 'myCubicHorizontal') {
			proxy.$modal
				.confirm('是否需要删除已经选中的边', '警告', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					cancelButtonClass: 'confirm-rigth-cancel-button',
					type: 'warning',
				})
				.then(() => {
					//如果线没有连接两端，那么目标为对象，如果连接目标为string
					if (typeof nodeModel.target === 'object') {
						searchHandler();
						return;
					}
					deleteLink({
						nodeId: nodeModel.target,
						parentNodeId: nodeModel.source,
						systemId: formData.systemId,
					}).then((res) => {
						if (res.code === 0) {
							graph.removeItem(graph.findById(nodeModel.id));
							proxy.$modal.msgSuccess('删除成功');
						} else {
							proxy.$modal.msgError('删除失败');
						}
					});
					currentContextItem.value = null;
				})
				.catch(function () {
					//proxy.$modal.msgError("删除失败");
				});
		} else {
			deleteLabel.value = '请选择已选中的节点' + nodeModel.name + '的删除方式';
			deleteDialogOpen.value = true;
		}
	}
}
// 删除选中的节点
function deleteNodeHandle() {
	const nodeModel = currentContextItem.value.getModel();
	deleteComponentInfo({
		id: nodeModel.id,
		systemId: formData.systemId,
		isRecursiveDelete: isRecursiveDelete.value,
	}).then((res) => {
		if (res.code === 0) {
			searchHandler();
			proxy.$modal.msgSuccess('删除成功');
		} else {
			proxy.$modal.msgError('删除失败');
		}
	});
	currentContextItem.value = null;
	handleCloseDeleteNode();
}
function handleCloseDeleteNode() {
	deleteDialogOpen.value = false;
	isRecursiveDelete.value = false;
}

function queryNodeInfo(id: any) {
	return getNodeInfo(id).then((res: ApiResponse) => {
		if (res.code === 0) {
			return res.data;
		}
		return {};
	});
}
//编辑选中的节点
function editNodeHandle(item?: any) {
	//设置高度
	addDialogForm.nodeEditHeight = '700px';
	const editItem = item || currentContextItem.value;
	nodeItem = editItem;
	if (editItem === null) {
		proxy.$modal.msgWarning('请选择要编辑的节点');
		return;
	} else {
		const nodeModel = editItem.getModel();
		let obj: any;
		getNodeInfo(nodeModel.id).then((res: ApiResponse) => {
			if (res.code === 0) {
				obj = res.data;

				let deviceT: any[] = [];
				dialogOptions.deviceOptions.forEach((d: any) => {
					const ddd = d.children.find((dd: any) => dd.label === obj.deviceType);
					if (ddd) {
						deviceT = [d.label, ddd.label];
					}
				});
				form.value = {
					id: nodeModel.id,
					componentName: obj.componentName,
					deviceType: deviceT,
					netType: obj.netType,
					connectType: obj.connectType,
					x: parseInt(nodeModel.x),
					y: parseInt(nodeModel.y),
				};
				open.nodeAttrDialog = true;
				title.value = '编辑';
				//新增节点，隐藏组件和服务资源，编辑节点显示
				addDialogForm.showComponentResource = true;
				//查询该端的组件
				searchComponentHandler(nodeModel.id);
			}
		});
	}
}
/* 下面是ip相关方法 */
// 查询IP
function searchComponentHandler(id: any, pageNum?: number) {
	if (id === null && currentContextItem.value !== null) {
		id = currentContextItem.value.getModel().id;
	}
	if (id !== null) {
		addDialogForm.component.formData.componentId = id;
		addDialogForm.component.formData.systemId = formData.systemId;
		if (pageNum) addDialogForm.component.formData.pageNum = 1;
		getAllIp(addDialogForm.component.formData).then((res: ApiResponse) => {
			addDialogForm.component.loading = false;
			if (res.code !== 0) {
				proxy.$modal.msgWarning(res.msg);
				return;
			}
			addDialogForm.component.componentList = res.data.records;
			addDialogForm.component.total = res.data.total;
		});
	}
}
//IP多选
function componentSelectionChangeHandle(selection: any) {
	addDialogForm.component.ids = selection.map((item: any) => item.id);
	addDialogForm.component.singleSelect = selection.length !== 1;
	addDialogForm.component.multipleSelect = !selection.length;
}
//增加IP
function addComponentHandle() {
	addDialogForm.component.adding = true;
	const data = addDialogForm.component.componentList;
	if (data !== null && data.length > 0) {
		for (let i = 0; i < data.length; i++) {
			const item = data[i];
			if (item.enable) {
				proxy.$modal.msgWarning('当前还有正在编辑的信息，请先保存或者取消再增加');
				return;
			}
		}
	}
	let temp = { ip: null, enable: true };
	addDialogForm.component.componentList.unshift(temp);
	proxy.$forceUpdate();
}
//修改IP
function updateComponentHandle() {
	const ids = addDialogForm.component.ids;
	if (ids === null || ids.length < 1) {
		proxy.$modal.msgWarning('请选择需要修改的IP');
		return;
	}
	const data = addDialogForm.component.componentList;
	if (data !== null && data.length > 0) {
		let item = data.find((d: any) => d.id === ids[0]);
		const updateInx = data.indexOf(item);
		item.enable = true;
		item.oriIp = item.ip;
		addDialogForm.component.componentList.splice(updateInx, 1, item);
	}
}
//删除IP
function deleteComponentHandle() {
	const ids = addDialogForm.component.ids;
	if (ids === null || ids.length === 0) {
		proxy.$modal.msgWarning('请选择要删除的IP');
		return;
	}
	proxy.$modal
		.confirm('是否需要删除已经选中的IP信息', '警告', {
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			cancelButtonClass: 'confirm-rigth-cancel-button',
			type: 'warning',
		})
		.then(() => {
			const nodeModel = currentContextItem.value.getModel();
			deleteIpConfig(ids[0]).then((res) => {
				if (res.code === 0) {
					proxy.$modal.msgSuccess('删除成功');
					//查询该节点的IP
					searchComponentHandler(nodeModel.id);
					//移除已经删除的IP
					const data = addDialogForm.component.componentList;
					let tempArr = [];
					for (let i = 0; i < data.length; i++) {
						let flag = 0;
						const item = data[i];
						for (let j = 0; j < ids.length; j++) {
							if (item.id === ids[j]) {
								flag = 1;
							}
						}
						if (flag === 0) {
							tempArr.push(item);
						}
					}
					addDialogForm.component.componentList = tempArr;
					//更新组件信息，以便鼠标移到节点显示
					const nodeData = JSON.parse(JSON.stringify(form.value));
					nodeData.id = nodeItem.getModel().id;
					nodeData.ipList = tempArr;
				} else {
					proxy.$modal.msgError('删除失败');
				}
			});
		})
		.catch(() => {});
}
//保存IP
function saveComponentHandle() {
	const data = addDialogForm.component.componentList;
	if (data !== null && data.length > 0) {
		let item: any = null;
		for (let i = 0; i < data.length; i++) {
			if (data[i].enable) {
				item = data[i];
			}
		}
		if (item !== null && item.enable) {
			if (item.ip === null || item.ip === '') {
				proxy.$modal.msgWarning('ip必填');
				return;
			}
			if (
				!/^((1[0-9][0-9]\.)|(2[0-4][0-9]\.)|(25[0-5]\.)|([1-9][0-9]\.)|([0-9]\.)){3}((1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])|([1-9][0-9])|([0-9]))$/.test(
					item.ip
				)
			) {
				proxy.$modal.msgWarning('ip不合法');
				return;
			}
			const nodeModel = currentContextItem.value.getModel();
			if (item.id) {
				// 修改
				updateIpConfig({
					id: item.id,
					ip: item.ip,
				}).then((res) => {
					if (res.code === 0) {
						proxy.$modal.msgSuccess('保存成功');
						//查询该节点的IP
						searchComponentHandler(nodeModel.id);
						item.enable = false;
						addDialogForm.component.adding = false;
						proxy.$refs.componentTable.clearSelection();
						//更新组件信息，以便鼠标移到节点显示
						const nodeData = JSON.parse(JSON.stringify(form.value));
						nodeData.id = nodeItem.getModel().id;
						nodeData.ipList = data;
					} else {
						proxy.$modal.msgError('保存失败');
					}
				});
			} else {
				// 新增
				addIpConfig({
					componentId: nodeModel.id,
					ip: item.ip,
				}).then((res) => {
					if (res.code === 0) {
						proxy.$modal.msgSuccess('保存成功');
						//查询该节点的IP
						searchComponentHandler(nodeModel.id);
						item.enable = false;
						addDialogForm.component.adding = false;
						proxy.$refs.componentTable.clearSelection();
						//更新组件信息，以便鼠标移到节点显示
						const nodeData = JSON.parse(JSON.stringify(form.value));
						nodeData.id = nodeItem.getModel().id;
						nodeData.ipList = data;
					} else {
						proxy.$modal.msgError('保存失败');
					}
				});
			}
		} else {
			proxy.$modal.msgWarning('没有要保存的信息');
		}
	}
}
//取消
function cancelComponentHandle() {
	const data = addDialogForm.component.componentList;
	let flag = true;
	if (data !== null && data.length > 0) {
		// 取消修改
		let item = data.find((d: any) => d.enable && d.id);
		if (item) {
			const updateInx = data.indexOf(item);
			item.ip = item.oriIp;
			item.enable = false;
			addDialogForm.component.componentList.splice(updateInx, 1, item);
			flag = false;
		}
		// 取消新增
		let addItem = data.find((d: any) => d.enable && !d.id);
		if (addItem) {
			addDialogForm.component.componentList.splice(0, 1);
			flag = false;
		}
	}
	if (flag) {
		proxy.$modal.msgWarning('没有可取消的信息');
	}
}
// 切换显示隐藏组件
function toggleShowComponent() {
	if (isShowComponent.value) {
		hideComponentFun();
	} else {
		showComponentFun();
	}
	isShowComponent.value = !isShowComponent.value;
}
// 显示组件方法
function showComponentFun() {
	graph.getNodes().forEach((node: any) => {
		const groups = node.getContainer().get('children');
		groups[groups.length - 1].show();
	});
	document.getElementById('showOrHideText')!.innerText = '显示';
	(document.getElementsByClassName('show-component-back')[0] as HTMLElement).style.backgroundImage = 'url(' + minimapPng + ')';
}
// 隐藏组件方法
function hideComponentFun() {
	graph.getNodes().forEach((node: any) => {
		const groups = node.getContainer().get('children');
		groups[groups.length - 1].hide();
	});
	document.getElementById('showOrHideText')!.innerText = '隐藏';
	(document.getElementsByClassName('show-component-back')[0] as HTMLElement).style.backgroundImage = 'url(' + minimapDisabledPng + ')';
}
// 按钮css 控制
function buttonIsDisabled(val: any) {
	if (val) {
		return 'disabled';
	}
	return 'enabled';
}
// 关闭弹窗
function handlerClosed() {
	searchHandler();
}
// 请求弹框的下拉列表
getDeviceInfo().then((res: ApiResponse) => {
	const data = res.data;
	data.forEach((d: any) => {
		let child: any[] = [];
		if (d.menuInfos) {
			d.menuInfos.forEach((dd: any) => {
				child.push({
					label: dd.menuName,
					value: dd.menuName,
				});
			});
		}
		dialogOptions.deviceOptions.push({
			label: d.menuName,
			value: d.menuName,
			children: child,
		});
	});
});
queryDictByType('net_type').then((res) => {
	if (res.code === 0) {
		dialogOptions.netOptions = res.data;
	}
});
</script>

<style rel="stylesheet/scss" lang="scss">
.it-road-editor-container {
	#componentDiv .el-table {
		color: #171616;
	}

	#container {
		position: relative;
		border: 2px solid #dcdfe6;
		border-radius: 6px;
	}

	.g6-component-toolbar {
		left: 0;
		top: 0;
		right: 0;
		margin: 0 auto;
		background-color: #2f5a86;
		color: #ffffff;

		ul {
			margin-block-start: 0;
			margin-block-end: 0;

			li {
				margin-right: 32px;
			}
		}

		.add-back {
			height: 40px;
			width: 40px;
			background-image: url('@/assets/images/admin/topology/add.png');
			background-repeat: no-repeat;
			background-position: center;
			background-size: 100% 100%;
		}

		.edit-back {
			height: 40px;
			width: 40px;
			cursor: not-allowed;
			background-image: url('@/assets/images/admin/topology/edit-disabled.png');
			background-repeat: no-repeat;
			background-position: center;
			background-size: 100% 100%;
		}

		.delete-back {
			height: 40px;
			width: 40px;
			cursor: not-allowed;
			background-image: url('@/assets/images/admin/topology/delete-disabled.png');
			background-repeat: no-repeat;
			background-position: center;
			background-size: 100% 100%;
		}

		.show-component-back {
			height: 40px;
			width: 40px;
			cursor: pointer;
			background-image: url('@/assets/images/admin/topology/minimap-disabled.png');
			background-repeat: no-repeat;
			background-position: center;
			background-size: 100% 100%;
		}
	}

	.g6-node-tooltip {
		background-color: #ffffff;
		color: #1b2c5d;
		border-radius: 6px;
		padding: 10px;
		box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
	}

	.g6-contextMenu {
		background-color: #ffffff;
		border-radius: 6px;
		box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);

		ul {
			list-style-type: none;
			margin-block-start: 0;
			margin-block-end: 0;
			padding-inline-start: 0;

			li {
				padding: 10px 20px;
				cursor: pointer;

				&:hover {
					background-color: #f1f3f7;
				}
			}
		}
	}
}

/*增加端信息弹出框样式*/
.itroad-add-it-dialog {
	/*已经选中的分页样式*/
	.el-pagination.is-background .el-pager li:not(.disabled).active {
		background-color: #1c2b5d;
	}
}

/*增加端信息弹窗*/
.it-road-add-dialog-div {
	.segmentHeadDiv {
		margin-top: 10px;
		margin-bottom: 10px;
		margin-left: 30px;
		font-size: 15px;
	}

	.componentHeadDiv {
		margin-top: 10px;
		margin-bottom: 10px;
		margin-left: 30px;
		font-size: 15px;
	}

	.lineDivClass {
		height: 2px;
		margin: 0px auto;
		padding: 0px;
		background-color: #f5f5f5;
		overflow: hidden;
	}
}

#tab-ipPort .is-active {
	background-color: #06cbcb;
}

#componentDiv .el-tabs__header {
	margin: 0;
}
#componentDiv .el-tabs--card > .el-tabs__header {
	border-bottom: 0;
}
</style>

<style rel="stylesheet/scss" lang="scss" scoped>
// @import '@/assets/styles/admin/index.scss';

.icon-style {
	// color: $--admin-color-btn-title;
}

/*操作按钮启用*/
.enabled {
	// color: $--admin-color-btn-title;
	cursor: pointer;

	.icon-title {
		&:hover {
			// color: $--admin-color-btn-title-hover;
			text-decoration: underline;
		}

		&:active {
			// color: $--admin-color-btn-title-active;
		}
	}
}

/*操作按钮禁用*/
.disabled {
	// color: $--admin-color-btn-title-disabled;
	cursor: not-allowed;
}

.tip-text {
	font-size: 12px;
	color: #999999;
	margin: 10px 0 10px 10px;
}
</style>
